#include <boost/crc.hpp>
#include <opts/po_wrapper.hpp>
#include <fstream>
#include <array>
#include <sstream>

constexpr size_t BUFFER_SIZE = 8192;

int main(int argc, char** argv)
{
    Opts::Instance().SetDescription("CRC check options");
    Opts::Instance().AddOption(
        "file,f",
        po::value<std::vector<std::string>>()->required()->multitoken(),
        "files to check");
    Opts::Instance().Parse(argc, argv);
    auto const& v = Opts::Instance().Get<std::vector<std::string>>("file");
    boost::crc_32_type result;
    std::stringstream ss;
    ss << "CRC-32 check sum for file:\n";
    for (auto const& f : v)
    {
        std::ifstream ifs(f, std::ios::binary);
        if (ifs)
        {
            ss << f << ", ";
            do
            {
                std::array<char, BUFFER_SIZE> buffer;
                ifs.read(buffer.data(), buffer.size() - 1);
                result.process_bytes(buffer.data(), ifs.gcount());
            } while (ifs);
        }
        else
        {
            std::cerr << "file: " << f << " open failed\n";
        }
    }
    ss << "\nis: " << std::hex << std::uppercase << result.checksum();
    std::cout << ss.str() << std::endl;
    return 0;
}